Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(withTableSettings): isSelected -> selected, isRequired -> required #1478

Merged
merged 17 commits into from
Apr 9, 2024

Conversation

GermanVor
Copy link
Contributor

No description provided.

@GermanVor GermanVor requested a review from Raubzeug as a code owner April 3, 2024 10:08
@gravity-ui-bot
Copy link
Contributor

Playwright Test Component is ready.

@gravity-ui-bot
Copy link
Contributor

Preview is ready.

@korvin89 korvin89 changed the title fix(withTbleSettings): isSelected -> selected fix(withTbleSettings): isSelected -> selected, isRequired -> required Apr 3, 2024
@teleginzhenya teleginzhenya self-requested a review April 3, 2024 10:19
Copy link
Contributor

@amje amje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It breaks current behaviour

@@ -263,7 +263,7 @@ const MyTable1 = withTableSettings({sortable: false})(Table);
```ts
type TableSettingsData = Array<{
id: string;
isSelected?: boolean;
selected?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? It's a breaking change

Copy link
Contributor

@teleginzhenya teleginzhenya Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, need to separate TableColumnSetupItem from TableSetting and return backward compatibility for TableColumnSetupItem only

@teleginzhenya teleginzhenya self-requested a review April 3, 2024 10:36
@@ -23,26 +23,26 @@ import './withTableSettings.scss';

export type TableSetting = {
id: string;
isSelected?: boolean;
selected?: boolean;
};

export type TableSettingsData = TableSetting[];

export type TableColumnSetupItem = TableSetting & {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export type TableColumnSetupItem = TableSetting & {
export type TableColumnSetupItem = {

Comment on lines 33 to 34
required?: boolean;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
required?: boolean;
};
selected?: boolean;
required?: boolean;
};

@@ -23,26 +23,26 @@ import './withTableSettings.scss';

export type TableSetting = {
id: string;
isSelected?: boolean;
selected?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
selected?: boolean;
isSelected?: boolean;

@GermanVor GermanVor force-pushed the withTableSettings-TableColumnSetupItem branch from 6dce2a5 to 645df56 Compare April 4, 2024 11:05
@GermanVor GermanVor requested a review from ValeraS as a code owner April 4, 2024 11:05
@GermanVor
Copy link
Contributor Author

GermanVor commented Apr 4, 2024

The problem is real

I rewrote TableColumnSetup but I did not think that it was public component. Interfaces TableColumnSetupItem also is public, but it is not connected with the TableSetting.

So, the best solution now to save backward compatibility in my opinion

  • stop exporting new TableColumnSetup
  • create separated TableColumnSetup component with code before I rewrote TableColumnSetup and export it

3616e97
645df56

What to do with new created TableColumnSetup component I do not know - probably delete it in future, but now save it for backward compatibility.

@teleginzhenya @Raubzeug

@teleginzhenya
Copy link
Contributor

@amje @korvin89 @Raubzeug @ValeraS we've discussed it and decided to return backward compatibility of public api of TableColumnSetup component for now. Then we'll discuss next steps about this component, should it be exported as separate component or not.

@GermanVor
Copy link
Contributor Author

@amje @korvin89 @Raubzeug @ValeraS

I begin rewrite new TableColumnSetup with the props of old one and I have new thoughts:

  • If I rewrite a new component (TableColumnSetup with TreeSelect) for the old ones, then I risk breaking the new component and the old component (TableColumnSetup with List).

  • The old component had props, which it is unclear how to apply to the new component (for example filter - there is no such property in TreeSelect)

  • The behavior of the old component is slightly different from the new one - in the new component we allow the required columns to be moved, but we do not allow to hide them, while in old component case we moved required columns at the start of the list, without opportunity move them.

  • The old component had the className option - it is not difficult to return it, but if the users used complex selectors, they are very likely will be broken cause TreeSelect probably is not comparable with List and Popup.

The best way to save backward compatibility in my opinion will be create TableColumnSetup with old code (code before i rewrote TableColumnSetup with TreeSelect) and export it instead of TableColumnSetup from withTableSettings.

In this case we 100% sure that new component will not be broken, users that use TableColumnSetup will get back component that they expected, old component 100% will not be broken.

And after that we will think what to do with TableColumnSetup.

@@ -18,7 +18,7 @@ import type {
import type {ListItemViewProps} from '../../../../useList';
import {ListContainerView, ListItemView} from '../../../../useList';
import {block} from '../../../../utils/cn';
import type {TableColumnSetupItem, TableSetting} from '../withTableSettings';
import type {TableSetting} from '../withTableSettings';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a circular dependency here, let's avoid such a case.

@@ -0,0 +1 @@
export * from './TableColumnSetup';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GermanVor GermanVor force-pushed the withTableSettings-TableColumnSetupItem branch 2 times, most recently from 2b05fc1 to 2c4bb9a Compare April 6, 2024 01:01
@@ -288,7 +288,7 @@ describe('withTableSettings', () => {

await userEvent.click(screen.getByRole('button', {name: 'Table settings'}));
await userEvent.click(await screen.findByRole('button', {name: 'description'}));
await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
await userEvent.click(screen.getByRole('button', {name: 'button_apply'}));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have no idea why it is broken now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because you test component const TableWithSettings = withTableSettings<SomeItem>(Table); . And keysets are taken from https://github.com/gravity-ui/uikit/tree/839d503f378e23eef87887866d20973bcd174fb4/src/components/Table/hoc/withTableSettings/i18n

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In separate PR, I do not know what happened with this place

let lastStickyLeftIdx = 0;
for (; lastStickyLeftIdx !== visibleFlattenIds.length; lastStickyLeftIdx++) {
const visibleFlattenId = visibleFlattenIds[lastStickyLeftIdx];
const item = items.find((item) => item.id === visibleFlattenId) as Item | undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IsaevAlexandr ListItemType generic works bad.
Do not know why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startSlot: tableColumnItem.isRequired ? <Icon data={Lock} /> : undefined,
hasSelectionIcon,
selected: hasSelectionIcon ? tableColumnItem.isSelected : undefined,
};
});
};

const prepareStikyState = (items: ListItemType<Item>[], visibleFlattenIds: string[]) => {
let lastStickyLeftIdx = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left and right names are obsolete in our code base, please use start and end instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 90 to 106
const stickyLeftItemIdList: string[] = [];
for (let i = 0; i < lastStickyLeftIdx; i++) {
const visibleFlattenId = visibleFlattenIds[i];
stickyLeftItemIdList.push(visibleFlattenId);
}

const sortableItemIdList: string[] = [];
for (let i = lastStickyLeftIdx; i < firstStickyRightIdx; i++) {
const visibleFlattenId = visibleFlattenIds[i];
sortableItemIdList.push(visibleFlattenId);
}

const stickyRightItemIdList: string[] = [];
for (let i = firstStickyRightIdx; i < visibleFlattenIds.length; i++) {
const visibleFlattenId = visibleFlattenIds[i];
stickyRightItemIdList.push(visibleFlattenId);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const stickyLeftItemIdList: string[] = [];
for (let i = 0; i < lastStickyLeftIdx; i++) {
const visibleFlattenId = visibleFlattenIds[i];
stickyLeftItemIdList.push(visibleFlattenId);
}
const sortableItemIdList: string[] = [];
for (let i = lastStickyLeftIdx; i < firstStickyRightIdx; i++) {
const visibleFlattenId = visibleFlattenIds[i];
sortableItemIdList.push(visibleFlattenId);
}
const stickyRightItemIdList: string[] = [];
for (let i = firstStickyRightIdx; i < visibleFlattenIds.length; i++) {
const visibleFlattenId = visibleFlattenIds[i];
stickyRightItemIdList.push(visibleFlattenId);
}
const stickyLeftItemIdList = visibleFlattenIds.slice(0, lastStickyLeftIdx);
const sortableItemIdList = visibleFlattenIds.slice(lastStickyLeftIdx, firstStickyRightIdx);
const stickyRightItemIdList = visibleFlattenIds.slice(firstStickyRightIdx);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 91 to 96
const items = propsItems.map(({id, title, required, selected}) => ({
id,
title,
isRequired: required,
isSelected: selected,
}));
Copy link
Contributor

@ValeraS ValeraS Apr 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const items = propsItems.map(({id, title, required, selected}) => ({
id,
title,
isRequired: required,
isSelected: selected,
}));
const items = propsItems.map(({id, title, required, selected}) => ({
id,
title,
isRequired: required,
isSelected: selected,
sticky: required ? "start" : undefiend
}));

or add a sticky field to TableColumnSetupItem, otherwise the behavior of the component will be different from the previous one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GermanVor GermanVor force-pushed the withTableSettings-TableColumnSetupItem branch from de23fe0 to 839d503 Compare April 6, 2024 22:29
@@ -302,7 +365,7 @@ export const TableColumnSetup = (props: TableColumnSetupProps) => {

return (
<TreeSelect
className={tableColumnSetupCn}
className={b(null, className)}
mapItemDataToProps={identity}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to get rid of these warnings and not set unknown attributes on DOM elements
image

let's do next

Suggested change
mapItemDataToProps={identity}
mapItemDataToProps={({isRequired, isSelected, sticky, ...rest}) => rest}

and remove ...data from the commonProps in the renderDndItem function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or better instead of prepareDndItems and dndItems use mapItemToProps and items

Suggested change
mapItemDataToProps={identity}
mapItemDataToProps={mapItemToProps}
items={items}

where

function mapItemToProps(item: TableColumnSetupItem): ListItemCommonProps {
    return {
        id: item.id,
        title: item.title,
        startSlot: item.isRequired ? <Icon data={Lock} /> : undefined,
        hasSelectionIcon: !item.isRequired,
        selected: !item.isRequired ? tableColumnItem.isSelected : undefined,               
    };
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think main reason is here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isRequired?: boolean;
sticky?: TableColumnConfig<unknown>['sticky'];
};

type Item = TableColumnSetupItem &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is {id, isDragDisabled} needed? id is present in TableSetting and isDragDisabled is not used.

@@ -288,7 +288,7 @@ describe('withTableSettings', () => {

await userEvent.click(screen.getByRole('button', {name: 'Table settings'}));
await userEvent.click(await screen.findByRole('button', {name: 'description'}));
await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
await userEvent.click(screen.getByRole('button', {name: 'button_apply'}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because you test component const TableWithSettings = withTableSettings<SomeItem>(Table); . And keysets are taken from https://github.com/gravity-ui/uikit/tree/839d503f378e23eef87887866d20973bcd174fb4/src/components/Table/hoc/withTableSettings/i18n

@@ -288,7 +288,7 @@ describe('withTableSettings', () => {

await userEvent.click(screen.getByRole('button', {name: 'Table settings'}));
await userEvent.click(await screen.findByRole('button', {name: 'description'}));
await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
await userEvent.click(screen.getByRole('button', {name: 'button_apply'}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it be fixed?

const prepareDndItems = (tableColumnItems: TableColumnSetupItem[]) => {
return tableColumnItems.map<Item>((tableColumnItem) => {
const hasSelectionIcon = tableColumnItem.isRequired === false;
const prepareStikyState = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const prepareStikyState = (
const prepareStickyState = (

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,130 @@
import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we can't just move the component outside the Table?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is only to save backward compatibility with old TableColumnSetup, TableColumnSetup from Table is not exportable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simply move it up to the components. It should be the one component. Keep backward compatibility with old versions and add sticky feature

@GermanVor GermanVor force-pushed the withTableSettings-TableColumnSetupItem branch from 662224f to 79d33de Compare April 8, 2024 14:29
@@ -0,0 +1,130 @@
import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simply move it up to the components. It should be the one component. Keep backward compatibility with old versions and add sticky feature

@amje amje changed the title fix(withTbleSettings): isSelected -> selected, isRequired -> required fix(withTableSettings): isSelected -> selected, isRequired -> required Apr 9, 2024
@amje amje merged commit cf1dfb0 into main Apr 9, 2024
4 checks passed
@amje amje deleted the withTableSettings-TableColumnSetupItem branch April 9, 2024 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants